package lei.b_java数据类型;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @className: 数据的计算
 * @author: xl
 * @date: 2025/7/16 21:28
 * @Version: 1.0
 * @description:
 */

public class 数据的计算 {

    public static void main(String[] args) {


        /**
         * 二进制转换为十进制
         * 公式=系数* 基数的权次幂 （相加）
         */

        // 示例：二进制 1101 转十进制
        String binary = "1101";
        int decimal = Integer.parseInt(binary, 2);
        System.out.println("二进制 " + binary + " 转换为十进制: " + decimal);

        // 手动计算过程
        // 1101 = 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0
        //      = 1*8 + 1*4 + 0*2 + 1*1
        //      = 8 + 4 + 0 + 1 = 13
        System.out.println("计算过程: 1*8 + 1*4 + 0*2 + 1*1 = " + (1*8 + 1*4 + 0*2 + 1*1));
        System.out.println(0b1101);

        /**
         * 八进制转换为十进制 12
         * 手动计算过程:  12 = 1*8^1 + 2*8^0=10
         */

        System.out.println(012);


        /**
         * 默认是十进制
         */
        System.out.println(18);


        /**
         * 十六进制转换为十进制 abc  1=10，b=11，c=12
         * 计算公式：a*16^2 + b*16^1 + c*16^0= 10*16^2 + 11*16^1 + 12*16^0=2748
         */
        System.out.println(0xabc);









        // 原始值（包含浮点误差）
        float floatValue = 0.1f + 0.2f;       // 实际值 ≈ 0.30000001192092896
        double doubleValue = 0.1 + 0.2;       // 实际值 = 0.30000000000000004
        BigDecimal bigDecimalValue = new BigDecimal("0.1").add(new BigDecimal("0.2")); // 精确 0.3

        System.out.println("原始值: ");
        System.out.println("float:       " + floatValue);
        System.out.println("double:      " + doubleValue);
        System.out.println("BigDecimal:  " + bigDecimalValue);
        System.out.println("--------------------------------------");

        // 1. 四舍五入保留2位小数
        System.out.println("四舍五入 (RoundingMode.HALF_UP):");
        System.out.println("float:       " + roundFloat(floatValue, 2, RoundingMode.HALF_UP));
        System.out.println("double:      " + roundDouble(doubleValue, 2, RoundingMode.HALF_UP));
        System.out.println("BigDecimal:  " + bigDecimalValue.setScale(2, RoundingMode.HALF_UP));
        System.out.println("Math float:       " + Math.round(floatValue)); //0
        System.out.println("Math double:      " + Math.round(doubleValue)); //0
        System.out.println();

        // 2. 向上取整保留2位小数
        System.out.println("向上取整 (RoundingMode.UP):");
        System.out.println("float:       " + roundFloat(floatValue, 2, RoundingMode.UP));
        System.out.println("double:      " + roundDouble(doubleValue, 2, RoundingMode.UP));
        System.out.println("BigDecimal:  " + bigDecimalValue.setScale(2, RoundingMode.UP));
        System.out.println("Math float:       " + Math.ceil(floatValue)); //1.0
        System.out.println("Math double:      " + Math.ceil(doubleValue)); //1.0
        System.out.println();

        // 3. 向下取整保留2位小数
        System.out.println("向下取整 (RoundingMode.DOWN):");
        System.out.println("float:       " + roundFloat(floatValue, 2, RoundingMode.DOWN));
        System.out.println("double:      " + roundDouble(doubleValue, 2, RoundingMode.DOWN));
        System.out.println("BigDecimal:  " + bigDecimalValue.setScale(2, RoundingMode.DOWN));
        System.out.println("Math float:       " + Math.floor(floatValue)); //0.0
        System.out.println("Math double:      " + Math.floor(doubleValue)); //0.0

        // 新增：直接截取两位小数（不四舍五入）
        System.out.println("\n===== 直接截取两位小数（不四舍五入） =====");
        System.out.println("float:       " + truncateFloatToTwo(floatValue));
        System.out.println("double:      " + truncateDoubleToTwo(doubleValue));
        System.out.println("BigDecimal:  " + bigDecimalValue.setScale(2, RoundingMode.DOWN));

    }

    // float精确舍入工具方法
    private static BigDecimal roundFloat(float value, int scale, RoundingMode mode) {
        return new BigDecimal(String.valueOf(value))  // 避免float精度误差
                .setScale(scale, mode);
    }

    // double精确舍入工具方法
    private static BigDecimal roundDouble(double value, int scale, RoundingMode mode) {
        return BigDecimal.valueOf(value)  // 使用valueOf避免构造误差
                .setScale(scale, mode);
    }

    // ===== 新增截断方法 =====
    public static float truncateFloatToTwo(float value) {
        return (float) (Math.floor(value * 100) / 100.0);
    }

    public static double truncateDoubleToTwo(double value) {
        return Math.floor(value * 100) / 100.0;
    }

}

